home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / util / libs / ttrender.lha / ttrender-2.0 / Developer / source / sfnt / ttsbit.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-06  |  51.5 KB  |  1,471 lines

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttsbit.c                                                               */
  4. /*                                                                         */
  5. /*    TrueType and OpenType embedded bitmap support (body).                */
  6. /*                                                                         */
  7. /*  Copyright 1996-2001 by                                                 */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.  
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_INTERNAL_STREAM_H
  22. #include FT_TRUETYPE_TAGS_H
  23. #include "ttsbit.h"
  24.  
  25. #include "sferrors.h"
  26.  
  27.  
  28.   /*************************************************************************/
  29.   /*                                                                       */
  30.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  31.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  32.   /* messages during execution.                                            */
  33.   /*                                                                       */
  34. #undef  FT_COMPONENT
  35. #define FT_COMPONENT  trace_ttsbit
  36.  
  37.  
  38.   /*************************************************************************/
  39.   /*                                                                       */
  40.   /* <Function>                                                            */
  41.   /*    blit_sbit                                                          */
  42.   /*                                                                       */
  43.   /* <Description>                                                         */
  44.   /*    Blits a bitmap from an input stream into a given target.  Supports */
  45.   /*    x and y offsets as well as byte padded lines.                      */
  46.   /*                                                                       */
  47.   /* <Input>                                                               */
  48.   /*    target      :: The target bitmap/pixmap.                           */
  49.   /*                                                                       */
  50.   /*    source      :: The input packed bitmap data.                       */
  51.   /*                                                                       */
  52.   /*    line_bits   :: The number of bits per line.                        */
  53.   /*                                                                       */
  54.   /*    byte_padded :: A flag which is true if lines are byte-padded.      */
  55.   /*                                                                       */
  56.   /*    x_offset    :: The horizontal offset.                              */
  57.   /*                                                                       */
  58.   /*    y_offset    :: The vertical offset.                                */
  59.   /*                                                                       */
  60.   /* <Note>                                                                */
  61.   /*    IMPORTANT: The x and y offsets are relative to the top corner of   */
  62.   /*               the target bitmap (unlike the normal TrueType           */
  63.   /*               convention).  A positive y offset indicates a downwards */
  64.   /*               direction!                                              */
  65.   /*                                                                       */
  66.   static void
  67.   blit_sbit( FT_Bitmap*  target,
  68.              FT_Byte*    source,
  69.              FT_Int      line_bits,
  70.              FT_Bool     byte_padded,
  71.              FT_Int      x_offset,
  72.              FT_Int      y_offset )
  73.   {
  74.     FT_Byte*   line_buff;
  75.     FT_Int     line_incr;
  76.     FT_Int     height;
  77.  
  78.     FT_UShort  acc;
  79.     FT_UInt    loaded;
  80.  
  81.  
  82.     /* first of all, compute starting write position */
  83.     line_incr = target->pitch;
  84.     line_buff = target->buffer;
  85.  
  86.     if ( line_incr < 0 )
  87.       line_buff -= line_incr * ( target->rows - 1 );
  88.  
  89.     line_buff += ( x_offset >> 3 ) + y_offset * line_incr;
  90.  
  91.     /***********************************************************************/
  92.     /*                                                                     */
  93.     /* We use the extra-classic `accumulator' trick to extract the bits    */
  94.     /* from the source byte stream.                                        */
  95.     /*                                                                     */
  96.     /* Namely, the variable `acc' is a 16-bit accumulator containing the   */
  97.     /* last `loaded' bits from the input stream.  The bits are shifted to  */
  98.     /* the upmost position in `acc'.                                       */
  99.     /*                                                                     */
  100.     /***********************************************************************/
  101.  
  102.     acc    = 0;  /* clear accumulator   */
  103.     loaded = 0;  /* no bits were loaded */
  104.  
  105.     for ( height = target->rows; height > 0; height-- )
  106.     {
  107.       FT_Byte*  cur   = line_buff;        /* current write cursor          */
  108.       FT_Int    count = line_bits;        /* # of bits to extract per line */
  109.       FT_Byte   shift = (FT_Byte)( x_offset & 7 ); /* current write shift  */
  110.       FT_Byte   space = (FT_Byte)( 8 - shift );
  111.  
  112.  
  113.       /* first of all, read individual source bytes */
  114.       if ( count >= 8 )
  115.       {
  116.         count -= 8;
  117.         {
  118.           do
  119.           {
  120.             FT_Byte  val;
  121.  
  122.  
  123.             /* ensure that there are at least 8 bits in the accumulator */
  124.             if ( loaded < 8 )
  125.             {
  126.               acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
  127.               loaded += 8;
  128.             }
  129.  
  130.             /* now write one byte */
  131.             val = (FT_Byte)( acc >> 8 );
  132.             if ( shift )
  133.             {
  134.               cur[0] |= (FT_Byte)( val >> shift );
  135.               cur[1] |= (FT_Byte)( val << space );
  136.             }
  137.             else
  138.               cur[0] |= val;
  139.  
  140.             cur++;
  141.             acc   <<= 8;  /* remove bits from accumulator */
  142.             loaded -= 8;
  143.             count  -= 8;
  144.  
  145.           } while ( count >= 0 );
  146.         }
  147.  
  148.         /* restore `count' to correct value */
  149.         count += 8;
  150.       }
  151.  
  152.       /* now write remaining bits (count < 8) */
  153.       if ( count > 0 )
  154.       {
  155.         FT_Byte  val;
  156.  
  157.  
  158.         /* ensure that there are at least `count' bits in the accumulator */
  159.         if ( (FT_Int)loaded < count )
  160.         {
  161.           acc    |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded ));
  162.           loaded += 8;
  163.         }
  164.  
  165.         /* now write remaining bits */
  166.         val     = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) );
  167.         cur[0] |= (FT_Byte)( val >> shift );
  168.  
  169.         if ( count > space )
  170.           cur[1] |= (FT_Byte)( val << space );
  171.  
  172.         acc   <<= count;
  173.         loaded -= count;
  174.       }
  175.  
  176.       /* now, skip to next line */
  177.       if ( byte_padded )
  178.       {
  179.         acc    = 0;
  180.         loaded = 0;   /* clear accumulator on byte-padded lines */
  181.       }
  182.  
  183.       line_buff += line_incr;
  184.     }
  185.   }
  186.  
  187.  
  188.   const FT_Frame_Field  sbit_metrics_fields[] =
  189.   {
  190. #undef  FT_STRUCTURE
  191. #define FT_STRUCTURE  TT_SBit_Metrics
  192.  
  193.     FT_FRAME_START( 8 ),
  194.       FT_FRAME_BYTE( height ),
  195.       FT_FRAME_BYTE( width ),
  196.  
  197.       FT_FRAME_CHAR( horiBearingX ),
  198.       FT_FRAME_CHAR( horiBearingY ),
  199.       FT_FRAME_BYTE( horiAdvance ),
  200.  
  201.       FT_FRAME_CHAR( vertBearingX ),
  202.       FT_FRAME_CHAR( vertBearingY ),
  203.       FT_FRAME_BYTE( vertAdvance ),
  204.     FT_FRAME_END
  205.   };
  206.  
  207.  
  208.   /*************************************************************************/
  209.   /*                                                                       */
  210.   /* <Function>                                                            */
  211.   /*    TT_Load_SBit_Const_Metrics                                         */
  212.   /*                                                                       */
  213.   /* <Description>                                                         */
  214.   /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */
  215.   /*                                                                       */
  216.   /* <Input>                                                               */
  217.   /*    range  :: The target range.                                        */
  218.   /*                                                                       */
  219.   /*    stream :: The input stream.                                        */
  220.   /*                                                                       */
  221.   /* <Return>                                                              */
  222.   /*    FreeType error code.  0 means success.                             */
  223.   /*                                                                       */
  224.   static FT_Error
  225.   Load_SBit_Const_Metrics( TT_SBit_Range*  range,
  226.                            FT_Stream       stream )
  227.   {
  228.     FT_Error  error;
  229.  
  230.  
  231.     if ( READ_ULong( range->image_size ) )
  232.       return error;
  233.  
  234.     return READ_Fields( sbit_metrics_fields, &range->metrics );
  235.   }
  236.  
  237.  
  238.   /*************************************************************************/
  239.   /*                                                                       */
  240.   /* <Function>                                                            */
  241.   /*    TT_Load_SBit_Range_Codes                                           */
  242.   /*                                                                       */
  243.   /* <Description>                                                         */
  244.   /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */
  245.   /*                                                                       */
  246.   /* <Input>                                                               */
  247.   /*    range        :: The target range.                                  */
  248.   /*                                                                       */
  249.   /*    stream       :: The input stream.                                  */
  250.   /*                                                                       */
  251.   /*    load_offsets :: A flag whether to load the glyph offset table.     */
  252.   /*                                                                       */
  253.   /* <Return>                                                              */
  254.   /*    FreeType error code.  0 means success.                             */
  255.   /*                                                                       */
  256.   static FT_Error
  257.   Load_SBit_Range_Codes( TT_SBit_Range*  range,
  258.                          FT_Stream       stream,
  259.                          FT_Bool         load_offsets )
  260.   {
  261.     FT_Error   error;
  262.     FT_ULong   count, n, size;
  263.     FT_Memory  memory = stream->memory;
  264.  
  265.  
  266.     if ( READ_ULong( count ) )
  267.       goto Exit;
  268.  
  269.     range->num_glyphs = count;
  270.  
  271.     /* Allocate glyph offsets table if needed */
  272.     if ( load_offsets )
  273.     {
  274.       if ( ALLOC_ARRAY( range->glyph_offsets, count, FT_ULong ) )
  275.         goto Exit;
  276.  
  277.       size = count * 4L;
  278.     }
  279.     else
  280.       size = count * 2L;
  281.  
  282.     /* Allocate glyph codes table and access frame */
  283.     if ( ALLOC_ARRAY ( range->glyph_codes, count, FT_UShort ) ||
  284.          ACCESS_Frame( size )                                 )
  285.       goto Exit;
  286.  
  287.     for ( n = 0; n < count; n++ )
  288.     {
  289.       range->glyph_codes[n] = GET_UShort();
  290.  
  291.       if ( load_offsets )
  292.         range->glyph_offsets[n] = (FT_ULong)range->image_offset +
  293.                                   GET_UShort();
  294.     }
  295.  
  296.     FORGET_Frame();
  297.  
  298.   Exit:
  299.     return error;
  300.   }
  301.  
  302.  
  303.   /*************************************************************************/
  304.   /*                                                                       */
  305.   /* <Function>                                                            */
  306.   /*    TT_Load_SBit_Range                                                 */
  307.   /*                                                                       */
  308.   /* <Description>                                                         */
  309.   /*    Loads a given `EBLC' index/range table.                            */
  310.   /*                                                                       */
  311.   /* <Input>                                                               */
  312.   /*    range  :: The target range.                                        */
  313.   /*                                                                       */
  314.   /*    stream :: The input stream.                                        */
  315.   /*                                                                       */
  316.   /* <Return>                                                              */
  317.   /*    FreeType error code.  0 means success.                             */
  318.   /*                                                                       */
  319.   static FT_Error
  320.   Load_SBit_Range( TT_SBit_Range*  range,
  321.                    FT_Stream       stream )
  322.   {
  323.     FT_Error   error;
  324.     FT_Memory  memory = stream->memory;
  325.  
  326.  
  327.     switch( range->index_format )
  328.     {
  329.     case 1:   /* variable metrics with 4-byte offsets */
  330.     case 3:   /* variable metrics with 2-byte offsets */
  331.       {
  332.         FT_ULong  num_glyphs, n;
  333.         FT_Int    size_elem;
  334.         FT_Bool   large = FT_BOOL( range->index_format == 1 );
  335.  
  336.  
  337.         num_glyphs        = range->last_glyph - range->first_glyph + 1L;
  338.         range->num_glyphs = num_glyphs;
  339.         num_glyphs++;                       /* XXX: BEWARE - see spec */
  340.  
  341.         size_elem = large ? 4 : 2;
  342.  
  343.         if ( ALLOC_ARRAY( range->glyph_offsets,
  344.                           num_glyphs, FT_ULong )    ||
  345.              ACCESS_Frame( num_glyphs * size_elem ) )
  346.           goto Exit;
  347.  
  348.         for ( n = 0; n < num_glyphs; n++ )
  349.           range->glyph_offsets[n] = (FT_ULong)( range->image_offset +
  350.                                                   ( large ? GET_ULong()
  351.                                                           : GET_UShort() ) );
  352.         FORGET_Frame();
  353.       }
  354.       break;
  355.  
  356.     case 2:   /* all glyphs have identical metrics */
  357.       error = Load_SBit_Const_Metrics( range, stream );
  358.       break;
  359.  
  360.     case 4:
  361.       error = Load_SBit_Range_Codes( range, stream, 1 );
  362.       break;
  363.  
  364.     case 5:
  365.       error = Load_SBit_Const_Metrics( range, stream ) ||
  366.               Load_SBit_Range_Codes( range, stream, 0  );
  367.       break;
  368.  
  369.     default:
  370.       error = SFNT_Err_Invalid_File_Format;
  371.     }
  372.  
  373.   Exit:
  374.     return error;
  375.   }
  376.  
  377.  
  378.   /*************************************************************************/
  379.   /*                                                                       */
  380.   /* <Function>                                                            */
  381.   /*    TT_Load_SBit_Strikes                                               */
  382.   /*                                                                       */
  383.   /* <Description>                                                         */
  384.   /*    Loads the table of embedded bitmap sizes for this face.            */
  385.   /*                                                                       */
  386.   /* <Input>                                                               */
  387.   /*    face   :: The target face object.                                  */
  388.   /*                                                                       */
  389.   /*    stream :: The input stream.                                        */
  390.   /*                                                                       */
  391.   /* <Return>                                                              */
  392.   /*    FreeType error code.  0 means success.                             */
  393.   /*                                                                       */
  394.   FT_LOCAL_DEF FT_Error
  395.   TT_Load_SBit_Strikes( TT_Face    face,
  396.                         FT_Stream  stream )
  397.   {
  398.     FT_Error   error  = 0;
  399.     FT_Memory  memory = stream->memory;
  400.     FT_Fixed   version;
  401.     FT_ULong   num_strikes;
  402.     FT_ULong   table_base;
  403.  
  404.     const FT_Frame_Field  sbit_line_metrics_fields[] =
  405.     {
  406. #undef  FT_STRUCTURE
  407. #define FT_STRUCTURE  TT_SBit_Line_Metrics
  408.  
  409.       /* no FT_FRAME_START */
  410.         FT_FRAME_CHAR( ascender ),
  411.         FT_FRAME_CHAR( descender ),
  412.         FT_FRAME_BYTE( max_width ),
  413.  
  414.         FT_FRAME_CHAR( caret_slope_numerator ),
  415.         FT_FRAME_CHAR( caret_slope_denominator ),
  416.         FT_FRAME_CHAR( caret_offset ),
  417.  
  418.         FT_FRAME_CHAR( min_origin_SB ),
  419.         FT_FRAME_CHAR( min_advance_SB ),
  420.         FT_FRAME_CHAR( max_before_BL ),
  421.         FT_FRAME_CHAR( min_after_BL ),
  422.         FT_FRAME_CHAR( pads[0] ),
  423.         FT_FRAME_CHAR( pads[1] ),
  424.       FT_FRAME_END
  425.     };
  426.  
  427.     const FT_Frame_Field  strike_start_fields[] =
  428.     {
  429. #undef  FT_STRUCTURE
  430. #define FT_STRUCTURE  TT_SBit_Strike
  431.  
  432.       /* no FT_FRAME_START */
  433.         FT_FRAME_ULONG( ranges_offset ),
  434.         FT_FRAME_SKIP_LONG,
  435.         FT_FRAME_ULONG( num_ranges ),
  436.         FT_FRAME_ULONG( color_ref ),
  437.       FT_FRAME_END
  438.     };
  439.  
  440.     const FT_Frame_Field  strike_end_fields[] =
  441.     {
  442.       /* no FT_FRAME_START */
  443.         FT_FRAME_USHORT( start_glyph ),
  444.         FT_FRAME_USHORT( end_glyph ),
  445.         FT_FRAME_BYTE  ( x_ppem ),
  446.         FT_FRAME_BYTE  ( y_ppem ),
  447.         FT_FRAME_BYTE  ( bit_depth ),
  448.         FT_FRAME_CHAR  ( flags ),
  449.       FT_FRAME_END
  450.     };
  451.  
  452.  
  453.     face->num_sbit_strikes = 0;
  454.  
  455.     /* this table is optional */
  456.     error = face->goto_table( face, TTAG_EBLC, stream, 0 );
  457.     if ( error )
  458.       error = face->goto_table( face, TTAG_bloc, stream, 0 );
  459.     if ( error )
  460.       goto Exit;
  461.  
  462.     table_base = FILE_Pos();
  463.     if ( ACCESS_Frame( 8L ) )
  464.       goto Exit;
  465.  
  466.     version     = GET_Long();
  467.     num_strikes = GET_ULong();
  468.  
  469.     FORGET_Frame();
  470.  
  471.     /* check version number and strike count */
  472.     if ( version     != 0x00020000L ||
  473.          num_strikes >= 0x10000L    )
  474.     {
  475.       FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" ));
  476.       error = SFNT_Err_Invalid_File_Format;
  477.  
  478.       goto Exit;
  479.     }
  480.  
  481.     /* allocate the strikes table */
  482.     if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) )
  483.       goto Exit;
  484.  
  485.     face->num_sbit_strikes = num_strikes;
  486.  
  487.     /* now read each strike table separately */
  488.     {
  489.       TT_SBit_Strike*  strike = face->sbit_strikes;
  490.       FT_ULong         count  = num_strikes;
  491.  
  492.  
  493.       if ( ACCESS_Frame( 48L * num_strikes ) )
  494.         goto Exit;
  495.  
  496.       while ( count > 0 )
  497.       {
  498.         if ( READ_Fields( strike_start_fields, strike )             ||
  499.              READ_Fields( sbit_line_metrics_fields, &strike->hori ) ||
  500.              READ_Fields( sbit_line_metrics_fields, &strike->vert ) ||
  501.              READ_Fields( strike_end_fields, strike )               )
  502.           break;
  503.  
  504.         count--;
  505.         strike++;
  506.       }
  507.  
  508.       FORGET_Frame();
  509.     }
  510.  
  511.     /* allocate the index ranges for each strike table */
  512.     {
  513.       TT_SBit_Strike*  strike = face->sbit_strikes;
  514.       FT_ULong         count  = num_strikes;
  515.  
  516.  
  517.       while ( count > 0 )
  518.       {
  519.         TT_SBit_Range*  range;
  520.         FT_ULong        count2 = strike->num_ranges;
  521.  
  522.  
  523.         if ( ALLOC_ARRAY( strike->sbit_ranges,
  524.                           strike->num_ranges,
  525.                           TT_SBit_Range ) )
  526.           goto Exit;
  527.  
  528.         /* read each range */
  529.         if ( FILE_Seek( table_base + strike->ranges_offset ) ||
  530.              ACCESS_Frame( strike->num_ranges * 8L )         )
  531.           goto Exit;
  532.  
  533.         range = strike->sbit_ranges;
  534.         while ( count2 > 0 )
  535.         {
  536.           range->first_glyph  = GET_UShort();
  537.           range->last_glyph   = GET_UShort();
  538.           range->table_offset = table_base + strike->ranges_offset
  539.                                  + GET_ULong();
  540.           count2--;
  541.           range++;
  542.         }
  543.  
  544.         FORGET_Frame();
  545.  
  546.         /* Now, read each index table */
  547.         count2 = strike->num_ranges;
  548.         range  = strike->sbit_ranges;
  549.         while ( count2 > 0 )
  550.         {
  551.           /* Read the header */
  552.           if ( FILE_Seek( range->table_offset ) ||
  553.                ACCESS_Frame( 8L )               )
  554.             goto Exit;
  555.  
  556.           range->index_format = GET_UShort();
  557.           range->image_format = GET_UShort();
  558.           range->image_offset = GET_ULong();
  559.  
  560.           FORGET_Frame();
  561.  
  562.           error = Load_SBit_Range( range, stream );
  563.           if ( error )
  564.             goto Exit;
  565.  
  566.           count2--;
  567.           range++;
  568.         }
  569.  
  570.         count--;
  571.         strike++;
  572.       }
  573.     }
  574.  
  575.   Exit:
  576.     return error;
  577.   }
  578.  
  579.  
  580.   /*************************************************************************/
  581.   /*                                                                       */
  582.   /* <Function>                                                            */
  583.   /*    TT_Free_SBit_Strikes                                               */
  584.   /*                                                                       */
  585.   /* <Description>                                                         */
  586.   /*    Releases the embedded bitmap tables.                               */
  587.   /*                                                                       */
  588.   /* <Input>                                                               */
  589.   /*    face :: The target face object.                                    */
  590.   /*                                                                       */
  591.   FT_LOCAL_DEF void
  592.   TT_Free_SBit_Strikes( TT_Face  face )
  593.   {
  594.     FT_Memory        memory       = face->root.memory;
  595.     TT_SBit_Strike*  strike       = face->sbit_strikes;
  596.     TT_SBit_Strike*  strike_limit = strike + face->num_sbit_strikes;
  597.  
  598.  
  599.     if ( strike )
  600.     {
  601.       for ( ; strike < strike_limit; strike++ )
  602.       {
  603.         TT_SBit_Range*  range       = strike->sbit_ranges;
  604.         TT_SBit_Range*  range_limit = range + strike->num_ranges;
  605.  
  606.  
  607.         if ( range )
  608.         {
  609.           for ( ; range < range_limit; range++ )
  610.           {
  611.             /* release the glyph offsets and codes tables */
  612.             /* where appropriate                          */
  613.             FREE( range->glyph_offsets );
  614.             FREE( range->glyph_codes );
  615.           }
  616.         }
  617.         FREE( strike->sbit_ranges );
  618.         strike->num_ranges = 0;
  619.       }
  620.       FREE( face->sbit_strikes );
  621.     }
  622.     face->num_sbit_strikes = 0;
  623.   }
  624.  
  625.  
  626.   FT_LOCAL_DEF FT_Error
  627.   TT_Set_SBit_Strike( TT_Face    face,
  628.                       FT_Int     x_ppem,
  629.                       FT_Int     y_ppem,
  630.                       FT_ULong  *astrike_index )
  631.   {
  632.     FT_Int  i;
  633.  
  634.  
  635.     if ( x_ppem < 0 || x_ppem > 255 ||
  636.          y_ppem < 1 || y_ppem > 255 )
  637.       return SFNT_Err_Invalid_PPem;
  638.  
  639.     for ( i = 0; i < face->num_sbit_strikes; i++ )
  640.     {
  641.       if ( ( face->sbit_strikes[i].y_ppem  == y_ppem )  &&
  642.            ( ( x_ppem == 0 ) ||
  643.              ( face->sbit_strikes[i].x_ppem == x_ppem ) ) )
  644.       {
  645.         *astrike_index = i;
  646.         return SFNT_Err_Ok;
  647.       }
  648.     }
  649.  
  650.     return SFNT_Err_Invalid_PPem;
  651.   }
  652.  
  653.  
  654.   /*************************************************************************/
  655.   /*                                                                       */
  656.   /* <Function>                                                            */
  657.   /*    Find_SBit_Range                                                    */
  658.   /*                                                                       */
  659.   /* <Description>                                                         */
  660.   /*    Scans a given strike's ranges and return, for a given glyph        */
  661.   /*    index, the corresponding sbit range, and `EBDT' offset.            */
  662.   /*                                                                       */
  663.   /* <Input>                                                               */
  664.   /*    glyph_index   :: The glyph index.                                  */
  665.   /*                                                                       */
  666.   /*    strike        :: The source/current sbit strike.                   */
  667.   /*                                                                       */
  668.   /* <Output>                                                              */
  669.   /*    arange        :: The sbit range containing the glyph index.        */
  670.   /*                                                                       */
  671.   /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
  672.   /*                                                                       */
  673.   /* <Return>                                                              */
  674.   /*    FreeType error code.  0 means the glyph index was found.           */
  675.   /*                                                                       */
  676.   static FT_Error
  677.   Find_SBit_Range( FT_UInt          glyph_index,
  678.                    TT_SBit_Strike*  strike,
  679.                    TT_SBit_Range**  arange,
  680.                    FT_ULong*        aglyph_offset )
  681.   {
  682.     TT_SBit_Range  *range, *range_limit;
  683.  
  684.  
  685.     /* check whether the glyph index is within this strike's */
  686.     /* glyph range                                           */
  687.     if ( glyph_index < (FT_UInt)strike->start_glyph ||
  688.          glyph_index > (FT_UInt)strike->end_glyph   )
  689.       goto Fail;
  690.  
  691.     /* scan all ranges in strike */
  692.     range       = strike->sbit_ranges;
  693.     range_limit = range + strike->num_ranges;
  694.     if ( !range )
  695.       goto Fail;
  696.  
  697.     for ( ; range < range_limit; range++ )
  698.     {
  699.       if ( glyph_index >= (FT_UInt)range->first_glyph &&
  700.            glyph_index <= (FT_UInt)range->last_glyph  )
  701.       {
  702.         FT_UShort  delta = (FT_UShort)( glyph_index - range->first_glyph );
  703.  
  704.  
  705.         switch ( range->index_format )
  706.         {
  707.         case 1:
  708.         case 3:
  709.           *aglyph_offset = range->glyph_offsets[delta];
  710.           break;
  711.  
  712.         case 2:
  713.           *aglyph_offset = range->image_offset +
  714.                            range->image_size * delta;
  715.           break;
  716.  
  717.         case 4:
  718.         case 5:
  719.           {
  720.             FT_ULong  n;
  721.  
  722.  
  723.             for ( n = 0; n < range->num_glyphs; n++ )
  724.             {
  725.               if ( (FT_UInt)range->glyph_codes[n] == glyph_index )
  726.               {
  727.                 if ( range->index_format == 4 )
  728.                   *aglyph_offset = range->glyph_offsets[n];
  729.                 else
  730.                   *aglyph_offset = range->image_offset +
  731.                                    n * range->image_size;
  732.                 goto Found;
  733.               }
  734.             }
  735.           }
  736.  
  737.           /* fall-through */
  738.           default:
  739.             goto Fail;
  740.         }
  741.  
  742.     Found:
  743.         /* return successfully! */
  744.         *arange  = range;
  745.         return 0;
  746.       }
  747.     }
  748.  
  749.   Fail:
  750.     *arange        = 0;
  751.     *aglyph_offset = 0;
  752.  
  753.     return SFNT_Err_Invalid_Argument;
  754.   }
  755.  
  756.  
  757.   /*************************************************************************/
  758.   /*                                                                       */
  759.   /* <Function>                                                            */
  760.   /*    Find_SBit_Image                                                    */
  761.   /*                                                                       */
  762.   /* <Description>                                                         */
  763.   /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */
  764.   /*    glyph, at a given strike.                                          */
  765.   /*                                                                       */
  766.   /* <Input>                                                               */
  767.   /*    face          :: The target face object.                           */
  768.   /*                                                                       */
  769.   /*    glyph_index   :: The glyph index.                                  */
  770.   /*                                                                       */
  771.   /*    strike_index  :: The current strike index.                         */
  772.   /*                                                                       */
  773.   /* <Output>                                                              */
  774.   /*    arange        :: The SBit range containing the glyph index.        */
  775.   /*                                                                       */
  776.   /*    astrike       :: The SBit strike containing the glyph index.       */
  777.   /*                                                                       */
  778.   /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
  779.   /*                                                                       */
  780.   /* <Return>                                                              */
  781.   /*    FreeType error code.  0 means success.  Returns                    */
  782.   /*    SFNT_Err_Invalid_Argument if no sbit exists for the requested      */
  783.   /*    glyph.                                                             */
  784.   /*                                                                       */
  785.   static FT_Error
  786.   Find_SBit_Image( TT_Face           face,
  787.                    FT_UInt           glyph_index,
  788.                    FT_ULong          strike_index,
  789.                    TT_SBit_Range*   *arange,
  790.                    TT_SBit_Strike*  *astrike,
  791.                    FT_ULong         *aglyph_offset )
  792.   {
  793.     FT_Error         error;
  794.     TT_SBit_Strike*  strike;
  795.  
  796.  
  797.     if ( !face->sbit_strikes                              ||
  798.          ( face->num_sbit_strikes <= (FT_Int)strike_index ) )
  799.       goto Fail;
  800.  
  801.     strike = &face->sbit_strikes[strike_index];
  802.  
  803.     error = Find_SBit_Range( glyph_index, strike,
  804.                              arange, aglyph_offset );
  805.     if ( error )
  806.       goto Fail;
  807.  
  808.     *astrike = strike;
  809.  
  810.     return SFNT_Err_Ok;
  811.  
  812.   Fail:
  813.     /* no embedded bitmap for this glyph in face */
  814.     *arange        = 0;
  815.     *astrike       = 0;
  816.     *aglyph_offset = 0;
  817.  
  818.     return SFNT_Err_Invalid_Argument;
  819.   }
  820.  
  821.  
  822.   /*************************************************************************/
  823.   /*                                                                       */
  824.   /* <Function>                                                            */
  825.   /*    Load_SBit_Metrics                                                  */
  826.   /*                                                                       */
  827.   /* <Description>                                                         */
  828.   /*    Gets the big metrics for a given SBit.                             */
  829.   /*                                                                       */
  830.   /* <Input>                                                               */
  831.   /*    stream      :: The input stream.                                   */
  832.   /*                                                                       */
  833.   /*    range       :: The SBit range containing the glyph.                */
  834.   /*                                                                       */
  835.   /* <Output>                                                              */
  836.   /*    big_metrics :: A big SBit metrics structure for the glyph.         */
  837.   /*                                                                       */
  838.   /* <Return>                                                              */
  839.   /*    FreeType error code.  0 means success.                             */
  840.   /*                                                                       */
  841.   /* <Note>                                                                */
  842.   /*    The stream cursor must be positioned at the glyph's offset within  */
  843.   /*    the `EBDT' table before the call.                                  */
  844.   /*                                                                       */
  845.   /*    If the image format uses variable metrics, the stream cursor is    */
  846.   /*    positioned just after the metrics header in the `EBDT' table on    */
  847.   /*    function exit.                                                     */
  848.   /*                                                                       */
  849.   static FT_Error
  850.   Load_SBit_Metrics( FT_Stream         stream,
  851.                      TT_SBit_Range*    range,
  852.                      TT_SBit_Metrics*  metrics )
  853.   {
  854.     FT_Error  error = SFNT_Err_Ok;
  855.  
  856.  
  857.     switch ( range->image_format )
  858.     {
  859.     case 1:
  860.     case 2:
  861.     case 8:
  862.       /* variable small metrics */
  863.       {
  864.         TT_SBit_Small_Metrics  smetrics;
  865.  
  866.         const FT_Frame_Field  sbit_small_metrics_fields[] =
  867.         {
  868. #undef  FT_STRUCTURE
  869. #define FT_STRUCTURE  TT_SBit_Small_Metrics
  870.  
  871.           FT_FRAME_START( 5 ),
  872.             FT_FRAME_BYTE( height ),
  873.             FT_FRAME_BYTE( width ),
  874.             FT_FRAME_CHAR( bearingX ),
  875.             FT_FRAME_CHAR( bearingY ),
  876.             FT_FRAME_BYTE( advance ),
  877.           FT_FRAME_END
  878.         };
  879.  
  880.  
  881.         /* read small metrics */
  882.         if ( READ_Fields( sbit_small_metrics_fields, &smetrics ) )
  883.           goto Exit;
  884.  
  885.         /* convert it to a big metrics */
  886.         metrics->height       = smetrics.height;
  887.         metrics->width        = smetrics.width;
  888.         metrics->horiBearingX = smetrics.bearingX;
  889.         metrics->horiBearingY = smetrics.bearingY;
  890.         metrics->horiAdvance  = smetrics.advance;
  891.  
  892.         /* these metrics are made up at a higher level when */
  893.         /* needed.                                          */
  894.         metrics->vertBearingX = 0;
  895.         metrics->vertBearingY = 0;
  896.         metrics->vertAdvance  = 0;
  897.       }
  898.       break;
  899.  
  900.     case 6:
  901.     case 7:
  902.     case 9:
  903.       /* variable big metrics */
  904.       if ( READ_Fields( sbit_metrics_fields, metrics ) )
  905.         goto Exit;
  906.       break;
  907.  
  908.     case 5:
  909.     default:  /* constant metrics */
  910.       if ( range->index_format == 2 || range->index_format == 5 )
  911.         *metrics = range->metrics;
  912.       else
  913.         return SFNT_Err_Invalid_File_Format;
  914.    }
  915.  
  916.   Exit:
  917.     return error;
  918.   }
  919.  
  920.  
  921.   /*************************************************************************/
  922.   /*                                                                       */
  923.   /* <Function>                                                            */
  924.   /*    Crop_Bitmap                                                        */
  925.   /*                                                                       */
  926.   /* <Description>                                                         */
  927.   /*    Crops a bitmap to its tightest bounding box, and adjusts its       */
  928.   /*    metrics.                                                           */
  929.   /*                                                                       */
  930.   /* <InOut>                                                               */
  931.   /*    map     :: The bitmap.                                             */
  932.   /*                                                                       */
  933.   /*    metrics :: The corresponding metrics structure.                    */
  934.   /*                                                                       */
  935.   static void
  936.   Crop_Bitmap( FT_Bitmap*        map,
  937.                TT_SBit_Metrics*  metrics )
  938.   {
  939.     /***********************************************************************/
  940.     /*                                                                     */
  941.     /* In this situation, some bounding boxes of embedded bitmaps are too  */
  942.     /* large.  We need to crop it to a reasonable size.                    */
  943.     /*                                                                     */
  944.     /*      ---------                                                      */
  945.     /*      |       |                -----                                 */
  946.     /*      |  ***  |                |***|                                 */
  947.     /*      |   *   |                | * |                                 */
  948.     /*      |   *   |    ------>     | * |                                 */
  949.     /*      |   *   |                | * |                                 */
  950.     /*      |   *   |                | * |                                 */
  951.     /*      |  ***  |                |***|                                 */
  952.     /*      ---------                -----                                 */
  953.     /*                                                                     */
  954.     /***********************************************************************/
  955.  
  956.     FT_Int    rows, count;
  957.     FT_Long   line_len;
  958.     FT_Byte*  line;
  959.  
  960.  
  961.     /***********************************************************************/
  962.     /*                                                                     */
  963.     /* first of all, check the top-most lines of the bitmap, and remove    */
  964.     /* them if they're empty.                                              */
  965.     /*                                                                     */
  966.     {
  967.       line     = (FT_Byte*)map->buffer;
  968.       rows     = map->rows;
  969.       line_len = map->pitch;
  970.  
  971.  
  972.       for ( count = 0; count < rows; count++ )
  973.       {
  974.         FT_Byte*  cur   = line;
  975.         FT_Byte*  limit = line + line_len;
  976.  
  977.  
  978.         for ( ; cur < limit; cur++ )
  979.           if ( cur[0] )
  980.             goto Found_Top;
  981.  
  982.         /* the current line was empty - skip to next one */
  983.         line  = limit;
  984.       }
  985.  
  986.     Found_Top:
  987.       /* check that we have at least one filled line */
  988.       if ( count >= rows )
  989.         goto Empty_Bitmap;
  990.  
  991.       /* now, crop the empty upper lines */
  992.       if ( count > 0 )
  993.       {
  994.         line = (FT_Byte*)map->buffer;
  995.  
  996.         MEM_Move( line, line + count * line_len,
  997.                   ( rows - count ) * line_len );
  998.  
  999.         metrics->height       = (FT_Byte)( metrics->height - count );
  1000.         metrics->horiBearingY = (FT_Char)( metrics->horiBearingY - count );
  1001.         metrics->vertBearingY = (FT_Char)( metrics->vertBearingY - count );
  1002.  
  1003.         map->rows -= count;
  1004.         rows      -= count;
  1005.       }
  1006.     }
  1007.  
  1008.     /***********************************************************************/
  1009.     /*                                                                     */
  1010.     /* second, crop the lower lines                                        */
  1011.     /*                                                                     */
  1012.     {
  1013.       line = (FT_Byte*)map->buffer + ( rows - 1 ) * line_len;
  1014.  
  1015.       for ( count = 0; count < rows; count++ )
  1016.       {
  1017.         FT_Byte*  cur   = line;
  1018.         FT_Byte*  limit = line + line_len;
  1019.  
  1020.  
  1021.         for ( ; cur < limit; cur++ )
  1022.           if ( cur[0] )
  1023.             goto Found_Bottom;
  1024.  
  1025.         /* the current line was empty - skip to previous one */
  1026.         line -= line_len;
  1027.       }
  1028.  
  1029.     Found_Bottom:
  1030.       if ( count > 0 )
  1031.       {
  1032.         metrics->height  = (FT_Byte)( metrics->height - count );
  1033.         rows            -= count;
  1034.         map->rows       -= count;
  1035.       }
  1036.     }
  1037.  
  1038.     /***********************************************************************/
  1039.     /*                                                                     */
  1040.     /* third, get rid of the space on the left side of the glyph           */
  1041.     /*                                                                     */
  1042.     do
  1043.     {
  1044.       FT_Byte*  limit;
  1045.  
  1046.  
  1047.       line  = (FT_Byte*)map->buffer;
  1048.       limit = line + rows * line_len;
  1049.  
  1050.       for ( ; line < limit; line += line_len )
  1051.         if ( line[0] & 0x80 )
  1052.           goto Found_Left;
  1053.  
  1054.       /* shift the whole glyph one pixel to the left */
  1055.       line  = (FT_Byte*)map->buffer;
  1056.       limit = line + rows * line_len;
  1057.  
  1058.       for ( ; line < limit; line += line_len )
  1059.       {
  1060.         FT_Int    n, width = map->width;
  1061.         FT_Byte   old;
  1062.         FT_Byte*  cur = line;
  1063.  
  1064.  
  1065.         old = (FT_Byte)(cur[0] << 1);
  1066.         for ( n = 8; n < width; n += 8 )
  1067.         {
  1068.           FT_Byte  val;
  1069.  
  1070.  
  1071.           val    = cur[1];
  1072.           cur[0] = (FT_Byte)( old | ( val >> 7 ) );
  1073.           old    = (FT_Byte)( val << 1 );
  1074.           cur++;
  1075.         }
  1076.         cur[0] = old;
  1077.       }
  1078.  
  1079.       map->width--;
  1080.       metrics->horiBearingX++;
  1081.       metrics->vertBearingX++;
  1082.       metrics->width--;
  1083.  
  1084.     } while ( map->width > 0 );
  1085.  
  1086.   Found_Left:
  1087.  
  1088.     /***********************************************************************/
  1089.     /*                                                                     */
  1090.     /* finally, crop the bitmap width to get rid of the space on the right */
  1091.     /* side of the glyph.                                                  */
  1092.     /*                                                                     */
  1093.     do
  1094.     {
  1095.       FT_Int    right = map->width - 1;
  1096.       FT_Byte*  limit;
  1097.       FT_Byte   mask;
  1098.  
  1099.  
  1100.       line  = (FT_Byte*)map->buffer + ( right >> 3 );
  1101.       limit = line + rows * line_len;
  1102.       mask  = (FT_Byte)( 0x80 >> ( right & 7 ) );
  1103.  
  1104.       for ( ; line < limit; line += line_len )
  1105.         if ( line[0] & mask )
  1106.           goto Found_Right;
  1107.  
  1108.       /* crop the whole glyph to the right */
  1109.       map->width--;
  1110.       metrics->width--;
  1111.  
  1112.     } while ( map->width > 0 );
  1113.  
  1114.   Found_Right:
  1115.     /* all right, the bitmap was cropped */
  1116.     return;
  1117.  
  1118.   Empty_Bitmap:
  1119.     map->width      = 0;
  1120.     map->rows       = 0;
  1121.     map->pitch      = 0;
  1122.     map->pixel_mode = ft_pixel_mode_mono;
  1123.   }
  1124.  
  1125.  
  1126.   static FT_Error
  1127.   Load_SBit_Single( FT_Bitmap*        map,
  1128.                     FT_Int            x_offset,
  1129.                     FT_Int            y_offset,
  1130.                     FT_Int            pix_bits,
  1131.                     FT_UShort         image_format,
  1132.                     TT_SBit_Metrics*  metrics,
  1133.                     FT_Stream         stream )
  1134.   {
  1135.     FT_Error  error;
  1136.  
  1137.  
  1138.     /* check that the source bitmap fits into the target pixmap */
  1139.     if ( x_offset < 0 || x_offset + metrics->width  > map->width ||
  1140.          y_offset < 0 || y_offset + metrics->height > map->rows  )
  1141.     {
  1142.       error = SFNT_Err_Invalid_Argument;
  1143.  
  1144.       goto Exit;
  1145.     }
  1146.  
  1147.     {
  1148.       FT_Int  glyph_width  = metrics->width;
  1149.       FT_Int  glyph_height = metrics->height;
  1150.       FT_Int  glyph_size;
  1151.       FT_Int  line_bits    = pix_bits * glyph_width;
  1152.       FT_Bool pad_bytes    = 0;
  1153.  
  1154.  
  1155.       /* compute size of glyph image */
  1156.       switch ( image_format )
  1157.       {
  1158.       case 1:  /* byte-padded formats */
  1159.       case 6:
  1160.         {
  1161.           FT_Int  line_length;
  1162.  
  1163.  
  1164.           switch ( pix_bits )
  1165.           {
  1166.           case 1:  line_length = ( glyph_width + 7 ) >> 3;   break;
  1167.           case 2:  line_length = ( glyph_width + 3 ) >> 2;   break;
  1168.           case 4:  line_length = ( glyph_width + 1 ) >> 1;   break;
  1169.           default: line_length =   glyph_width;
  1170.           }
  1171.  
  1172.           glyph_size = glyph_height * line_length;
  1173.           pad_bytes  = 1;
  1174.         }
  1175.         break;
  1176.  
  1177.       case 2:
  1178.       case 5:
  1179.       case 7:
  1180.         line_bits  =   glyph_width  * pix_bits;
  1181.         glyph_size = ( glyph_height * line_bits + 7 ) >> 3;
  1182.         break;
  1183.  
  1184.       default:  /* invalid format */
  1185.         return SFNT_Err_Invalid_File_Format;
  1186.       }
  1187.  
  1188.       /* Now read data and draw glyph into target pixmap       */
  1189.       if ( ACCESS_Frame( glyph_size ) )
  1190.         goto Exit;
  1191.  
  1192.       /* don't forget to multiply `x_offset' by `map->pix_bits' as */
  1193.       /* the sbit blitter doesn't make a difference between pixmap */
  1194.       /* depths.                                                   */
  1195.       blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
  1196.                  x_offset * pix_bits, y_offset );
  1197.  
  1198.       FORGET_Frame();
  1199.     }
  1200.  
  1201.   Exit:
  1202.     return error;
  1203.   }
  1204.  
  1205.  
  1206.   static FT_Error
  1207.   Load_SBit_Image( TT_SBit_Strike*   strike,
  1208.                    TT_SBit_Range*    range,
  1209.                    FT_ULong          ebdt_pos,
  1210.                    FT_ULong          glyph_offset,
  1211.                    FT_Bitmap*        map,
  1212.                    FT_Int            x_offset,
  1213.                    FT_Int            y_offset,
  1214.                    FT_Stream         stream,
  1215.                    TT_SBit_Metrics*  metrics )
  1216.   {
  1217.     FT_Memory  memory = stream->memory;
  1218.     FT_Error   error;
  1219.  
  1220.  
  1221.     /* place stream at beginning of glyph data and read metrics */
  1222.     if ( FILE_Seek( ebdt_pos + glyph_offset ) )
  1223.       goto Exit;
  1224.  
  1225.     error = Load_SBit_Metrics( stream, range, metrics );
  1226.     if ( error )
  1227.       goto Exit;
  1228.  
  1229.     /* this function is recursive.  At the top-level call, the */
  1230.     /* field map.buffer is NULL.  We thus begin by finding the */
  1231.     /* dimensions of the higher-level glyph to allocate the    */
  1232.     /* final pixmap buffer                                     */
  1233.     if ( map->buffer == 0 )
  1234.     {
  1235.       FT_Long  size;
  1236.  
  1237.  
  1238.       map->width = metrics->width;
  1239.       map->rows  = metrics->height;
  1240.  
  1241.       switch ( strike->bit_depth )
  1242.       {
  1243.       case 1:
  1244.         map->pixel_mode = ft_pixel_mode_mono;
  1245.         map->pitch      = ( map->width + 7 ) >> 3;
  1246.         break;
  1247.  
  1248.       case 2:
  1249.         map->pixel_mode = ft_pixel_mode_pal2;
  1250.         map->pitch      = ( map->width + 3 ) >> 2;
  1251.         break;
  1252.  
  1253.       case 4:
  1254.         map->pixel_mode = ft_pixel_mode_pal4;
  1255.         map->pitch      = ( map->width + 1 ) >> 1;
  1256.         break;
  1257.  
  1258.       case 8:
  1259.         map->pixel_mode = ft_pixel_mode_grays;
  1260.         map->pitch      = map->width;
  1261.         break;
  1262.  
  1263.       default:
  1264.         return SFNT_Err_Invalid_File_Format;
  1265.       }
  1266.  
  1267.       size = map->rows * map->pitch;
  1268.  
  1269.       /* check that there is no empty image */
  1270.       if ( size == 0 )
  1271.         goto Exit;     /* exit successfully! */
  1272.  
  1273.       if ( ALLOC( map->buffer, size ) )
  1274.         goto Exit;
  1275.     }
  1276.  
  1277.     switch ( range->image_format )
  1278.     {
  1279.     case 1:  /* single sbit image - load it */
  1280.     case 2:
  1281.     case 5:
  1282.     case 6:
  1283.     case 7:
  1284.       return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
  1285.                                range->image_format, metrics, stream );
  1286.  
  1287.     case 8:  /* compound format */
  1288.       FT_Skip_Stream( stream, 1L );
  1289.       /* fallthrough */
  1290.  
  1291.     case 9:
  1292.       break;
  1293.  
  1294.     default: /* invalid image format */
  1295.       return SFNT_Err_Invalid_File_Format;
  1296.     }
  1297.  
  1298.     /* All right, we have a compound format.  First of all, read */
  1299.     /* the array of elements.                                    */
  1300.     {
  1301.       TT_SBit_Component*  components;
  1302.       TT_SBit_Component*  comp;
  1303.       FT_UShort           num_components, count;
  1304.  
  1305.  
  1306.       if ( READ_UShort( num_components )                                ||
  1307.            ALLOC_ARRAY( components, num_components, TT_SBit_Component ) )
  1308.         goto Exit;
  1309.  
  1310.       count = num_components;
  1311.  
  1312.       if ( ACCESS_Frame( 4L * num_components ) )
  1313.         goto Fail_Memory;
  1314.  
  1315.       for ( comp = components; count > 0; count--, comp++ )
  1316.       {
  1317.         comp->glyph_code = GET_UShort();
  1318.         comp->x_offset   = GET_Char();
  1319.         comp->y_offset   = GET_Char();
  1320.       }
  1321.  
  1322.       FORGET_Frame();
  1323.  
  1324.       /* Now recursively load each element glyph */
  1325.       count = num_components;
  1326.       comp  = components;
  1327.       for ( ; count > 0; count--, comp++ )
  1328.       {
  1329.         TT_SBit_Range*   elem_range;
  1330.         TT_SBit_Metrics  elem_metrics;
  1331.         FT_ULong         elem_offset;
  1332.  
  1333.  
  1334.         /* find the range for this element */
  1335.         error = Find_SBit_Range( comp->glyph_code,
  1336.                                  strike,
  1337.                                  &elem_range,
  1338.                                  &elem_offset );
  1339.         if ( error )
  1340.           goto Fail_Memory;
  1341.  
  1342.         /* now load the element, recursively */
  1343.         error = Load_SBit_Image( strike,
  1344.                                  elem_range,
  1345.                                  ebdt_pos,
  1346.                                  elem_offset,
  1347.                                  map,
  1348.                                  x_offset + comp->x_offset,
  1349.                                  y_offset + comp->y_offset,
  1350.                                  stream,
  1351.                                  &elem_metrics );
  1352.         if ( error )
  1353.           goto Fail_Memory;
  1354.       }
  1355.  
  1356.     Fail_Memory:
  1357.       FREE( components );
  1358.     }
  1359.  
  1360.   Exit:
  1361.     return error;
  1362.   }
  1363.  
  1364.  
  1365.   /*************************************************************************/
  1366.   /*                                                                       */
  1367.   /* <Function>                                                            */
  1368.   /*    TT_Load_SBit_Image                                                 */
  1369.   /*                                                                       */
  1370.   /* <Description>                                                         */
  1371.   /*    Loads a given glyph sbit image from the font resource.  This also  */
  1372.   /*    returns its metrics.                                               */
  1373.   /*                                                                       */
  1374.   /* <Input>                                                               */
  1375.   /*    face         :: The target face object.                            */
  1376.   /*                                                                       */
  1377.   /*    strike_index :: The current strike index.                          */
  1378.   /*                                                                       */
  1379.   /*    glyph_index  :: The current glyph index.                           */
  1380.   /*                                                                       */
  1381.   /*    load_flags   :: The glyph load flags (the code checks for the flag */
  1382.   /*                    FT_LOAD_CROP_BITMAP).                              */
  1383.   /*                                                                       */
  1384.   /*    stream       :: The input stream.                                  */
  1385.   /*                                                                       */
  1386.   /* <Output>                                                              */
  1387.   /*    map          :: The target pixmap.                                 */
  1388.   /*                                                                       */
  1389.   /*    metrics      :: A big sbit metrics structure for the glyph image.  */
  1390.   /*                                                                       */
  1391.   /* <Return>                                                              */
  1392.   /*    FreeType error code.  0 means success.  Returns an error if no     */
  1393.   /*    glyph sbit exists for the index.                                   */
  1394.   /*                                                                       */
  1395.   /*  <Note>                                                               */
  1396.   /*    The `map.buffer' field is always freed before the glyph is loaded. */
  1397.   /*                                                                       */
  1398.   FT_LOCAL_DEF FT_Error
  1399.   TT_Load_SBit_Image( TT_Face           face,
  1400.                       FT_ULong          strike_index,
  1401.                       FT_UInt           glyph_index,
  1402.                       FT_UInt           load_flags,
  1403.                       FT_Stream         stream,
  1404.                       FT_Bitmap        *map,
  1405.                       TT_SBit_Metrics  *metrics )
  1406.   {
  1407.     FT_Error         error;
  1408.     FT_Memory        memory = stream->memory;
  1409.     FT_ULong         ebdt_pos, glyph_offset;
  1410.  
  1411.     TT_SBit_Strike*  strike;
  1412.     TT_SBit_Range*   range;
  1413.  
  1414.  
  1415.     /* Check whether there is a glyph sbit for the current index */
  1416.     error = Find_SBit_Image( face, glyph_index, strike_index,
  1417.                              &range, &strike, &glyph_offset );
  1418.     if ( error )
  1419.       goto Exit;
  1420.  
  1421.     /* now, find the location of the `EBDT' table in */
  1422.     /* the font file                                 */
  1423.     error = face->goto_table( face, TTAG_EBDT, stream, 0 );
  1424.     if ( error )
  1425.       error = face->goto_table( face, TTAG_bdat, stream, 0 );
  1426.     if (error)
  1427.       goto Exit;
  1428.  
  1429.     ebdt_pos = FILE_Pos();
  1430.  
  1431.     /* clear the bitmap & load the bitmap */
  1432.     if ( face->root.glyph->flags & ft_glyph_own_bitmap )
  1433.       FREE( map->buffer );
  1434.  
  1435.     map->rows = map->pitch = map->width = 0;
  1436.  
  1437.     error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
  1438.                              map, 0, 0, stream, metrics );
  1439.     if ( error )
  1440.       goto Exit;
  1441.  
  1442.     /* the glyph slot owns this bitmap buffer */
  1443.     face->root.glyph->flags |= ft_glyph_own_bitmap;
  1444.  
  1445.     /* setup vertical metrics if needed */
  1446.     if ( strike->flags & 1 )
  1447.     {
  1448.       /* in case of a horizontal strike only */
  1449.       FT_Int  advance;
  1450.  
  1451.  
  1452.       advance = strike->hori.ascender - strike->hori.descender;
  1453.  
  1454.       /* some heuristic values */
  1455.  
  1456.       metrics->vertBearingX = (FT_Char)(-metrics->width / 2 );
  1457.       metrics->vertBearingY = (FT_Char)( advance / 10 );
  1458.       metrics->vertAdvance  = (FT_Char)( advance * 12 / 10 );
  1459.     }
  1460.  
  1461.     /* Crop the bitmap now, unless specified otherwise */
  1462.     if ( load_flags & FT_LOAD_CROP_BITMAP )
  1463.       Crop_Bitmap( map, metrics );
  1464.  
  1465.   Exit:
  1466.     return error;
  1467.   }
  1468.  
  1469.  
  1470. /* END */
  1471.